package io.finer.erp.jeecg.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.finer.erp.jeecg.finance.entity.FinaNvoice;
import io.finer.erp.jeecg.finance.entity.FinaPayment;
import io.finer.erp.jeecg.finance.entity.FinaReceipt;
import io.finer.erp.jeecg.finance.mapper.FinaNvoiceMapper;
import io.finer.erp.jeecg.finance.mapper.FinaReceiptMapper;
import io.finer.erp.jeecg.finance.service.IFinaNvoiceService;
import io.finer.erp.jeecg.finance.vo.FinaNvoiceDto;
import io.finer.erp.jeecg.finance.vo.FinaNvoiceSumPrice;

import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

/**
 * @Description: 发票表单
 * @Author: jeecg-boot
 * @Date:   2021-03-23
 * @Version: V1.0
 */
@Service
public class FinaNvoiceServiceImpl extends ServiceImpl<FinaNvoiceMapper, FinaNvoice> implements IFinaNvoiceService {

    @Autowired
    private FinaNvoiceMapper nvoiceMapper;
    @Autowired
    private FinaReceiptServiceImpl finaReceiptService;
    @Autowired
    private FinaPaymentServiceImpl paymentService;


    @Override
    public List<FinaNvoice> selectNvoiceByNoOrPrice(String type){
        return nvoiceMapper.selectNvoiceByNoOrPrice(type);
    }


    @Override
    @Transactional
    public boolean addInvoiceOrReceipt(FinaNvoice finaNvoice){
    	this.save(finaNvoice);
//    	Calendar c = Calendar.getInstance();
//    	c.add(Calendar.MONTH, 0);
//        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        LambdaQueryWrapper<FinaReceipt> wrapper=new LambdaQueryWrapper<FinaReceipt> ();
        wrapper.eq(FinaReceipt::getCustomerId, finaNvoice.getCustomerId());
        wrapper.eq(FinaReceipt::getBillType,1);
        wrapper.gt(FinaReceipt::getNoneInvoicePrice, 0);
//        wrapper.lt(FinaReceipt::getCreateTime, c.getTime());
        wrapper.orderByAsc(FinaReceipt::getCreateTime);
        List<FinaReceipt> receipts= finaReceiptService.list(wrapper);
        BigDecimal s = finaNvoice.getInvoicePrice()==null?BigDecimal.ZERO:finaNvoice.getInvoicePrice();
        if(receipts!=null && receipts.size()>0){
            for (FinaReceipt receipt : receipts) {
            	BigDecimal noneInvoicePrice = receipt.getNoneInvoicePrice()==null?BigDecimal.ZERO:receipt.getNoneInvoicePrice();
                s = s.subtract(noneInvoicePrice);
                if (s.compareTo(BigDecimal.ZERO) < 0) {
                    //如果已收减去应收小于零。则将已收减去。
//                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
                    receipt.setNoneInvoicePrice(s.setScale(2, BigDecimal.ROUND_DOWN).abs());
                    receipt.setHxType("1");
                    finaReceiptService.updateById(receipt);
                    break;
                } else if (s.compareTo(BigDecimal.ZERO) >= 0) {
                    //如果已收减去应收大于0，则将应收改为平账并且继续对其他应收进行平账
//                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
                    receipt.setNoneInvoicePrice(BigDecimal.ZERO);
                    receipt.setHxType("9");
                    finaReceiptService.updateById(receipt);
                }
            }
        }
        return true;
    }


    @Override
    @Transactional
    public boolean addInvoiceOrFK(FinaNvoice finaNvoice){
    	this.save(finaNvoice);
        LambdaQueryWrapper<FinaPayment> wrapper=new LambdaQueryWrapper<FinaPayment> ();
        wrapper.eq(FinaPayment::getSupplierId, finaNvoice.getSupplierId());
        wrapper.eq(FinaPayment::getBillType,3);
        wrapper.gt(FinaPayment::getNoneInvoicePrice, 0);
        wrapper.orderByAsc(FinaPayment::getCreateTime);
        List<FinaPayment> receipts= paymentService.list(wrapper);
        if(receipts!=null && receipts.size()>0){
            BigDecimal s = finaNvoice.getInvoicePrice();
            for (FinaPayment receipt : receipts) {
            	BigDecimal noneInvoicePrice = receipt.getNoneInvoicePrice()==null?BigDecimal.ZERO:receipt.getNoneInvoicePrice();
                s = s.subtract(noneInvoicePrice);
                if (s.compareTo(BigDecimal.ZERO) < 0) {
                    //如果已收减去应收小于零。则将已收减去。
//                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
                    receipt.setNoneInvoicePrice(s.setScale(2, BigDecimal.ROUND_DOWN).abs());
                    receipt.setHxType("1");
                    paymentService.updateById(receipt);
                    break;
                } else if (s.compareTo(BigDecimal.ZERO) > 0) {
                    //如果已收减去应收大于0，则将应收改为平账并且继续对其他应收进行平账
//                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
                    receipt.setNoneInvoicePrice(BigDecimal.ZERO);
                    receipt.setHxType("0");
                    paymentService.updateById(receipt);
                }else{
                    //如果已收减去应收小于零。则将已收减去。
//                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
                    receipt.setNoneInvoicePrice(BigDecimal.ZERO);
                    receipt.setHxType("0");
                    paymentService.updateById(receipt);
                    break;
                }
            }
        }
        return true;
    }



    @Override
    public FinaNvoiceSumPrice getInvoiceSumPrice(String type,String customerName,String startTime,String endTime ){
        List<FinaNvoice> list=nvoiceMapper.getSumInvoice(type,customerName,startTime,endTime);
        FinaNvoiceSumPrice price = new FinaNvoiceSumPrice();
        BigDecimal ws = new BigDecimal("0");
        BigDecimal se = new BigDecimal("0");
        BigDecimal ys = new BigDecimal("0");
        Integer i=0;
        for (FinaNvoice nvoice : list) {
        	String rate = "0%";
			 if(oConvertUtils.isNotEmpty(nvoice.getTaxRate())) {
				 rate = nvoice.getTaxRate();
			 }
//			 获取税率
            String[] str=rate.split("%");
//			 计算税额
            BigDecimal tax=new BigDecimal(str[0]).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
            BigDecimal invoicePrice = nvoice.getInvoicePrice()==null?BigDecimal.ZERO:nvoice.getInvoicePrice();
            BigDecimal taxAmount=invoicePrice.multiply(tax);
            nvoice.setTaxAmount(taxAmount);//税额
            nvoice.setNoTaxPrice(invoicePrice.subtract(taxAmount));//无税金额
            nvoice.setTaxPrice(invoicePrice);//含税金额
            se=se.add(taxAmount);
            BigDecimal noTaxPrice = nvoice.getNoTaxPrice()==null?BigDecimal.ZERO:nvoice.getNoTaxPrice();
            ws=ws.add(noTaxPrice);
            BigDecimal taxPrice = nvoice.getTaxPrice()==null?BigDecimal.ZERO:nvoice.getTaxPrice();
            ys=ys.add(taxPrice);
            i++;
        }
        price.setTaxPrice(ys);
        price.setCount(i);
        price.setNoTaxPrice(ws);
        price.setTaxAmount(se);
        return price;
    }


	@Override
	@Transactional
	public boolean updateInvoiceOrReceipt(FinaNvoice finaNvoice) {
		// TODO Auto-generated method stub
		FinaNvoice nvoice = baseMapper.selectById(finaNvoice.getId());
		this.updateById(finaNvoice);
        LambdaQueryWrapper<FinaReceipt> wrapper=new LambdaQueryWrapper<FinaReceipt> ();
        wrapper.eq(FinaReceipt::getCustomerId, finaNvoice.getCustomerId());
        wrapper.eq(FinaReceipt::getBillType,1);
        wrapper.gt(FinaReceipt::getNoneInvoicePrice, 0);
        wrapper.orderByAsc(FinaReceipt::getCreateTime);
        List<FinaReceipt> receipts= finaReceiptService.list(wrapper);
        BigDecimal s = finaNvoice.getInvoicePrice()==null?BigDecimal.ZERO:finaNvoice.getInvoicePrice();
        BigDecimal n = nvoice.getInvoicePrice()==null?BigDecimal.ZERO:nvoice.getInvoicePrice();
		if(s.compareTo(n) > 0 ) {
			s = s.subtract(n);
	        if(receipts!=null && receipts.size()>0){
	            for (FinaReceipt receipt : receipts) {
	            	BigDecimal noneInvoicePrice = receipt.getNoneInvoicePrice()==null?BigDecimal.ZERO:receipt.getNoneInvoicePrice();
	                s = s.subtract(noneInvoicePrice);
	                if (s.compareTo(BigDecimal.ZERO) < 0) {
	                    //如果已收减去应收小于零。则将已收减去。
//	                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
	                    receipt.setNoneInvoicePrice(s.setScale(2, BigDecimal.ROUND_DOWN).abs());
	                    receipt.setHxType("1");
	                    finaReceiptService.updateById(receipt);
	                    break;
	                } else if (s.compareTo(BigDecimal.ZERO) > 0) {
	                    //如果已收减去应收大于0，则将应收改为平账并且继续对其他应收进行平账
//	                    receipt.setInvoicePrice(finaNvoice.getInvoicePrice());
	                    receipt.setNoneInvoicePrice(BigDecimal.ZERO);
	                    receipt.setHxType("0");
	                    finaReceiptService.updateById(receipt);
	                }else {
	                	receipt.setNoneInvoicePrice(BigDecimal.ZERO);
	                	receipt.setHxType("0");
	                    finaReceiptService.updateById(receipt);
	                    break;
	                }
	            }
	        }
		}
		if(s.compareTo(n) < 0 ) {
			this.updateById(finaNvoice);
			s = n.subtract(s);
	        if(receipts!=null && receipts.size()>0){
	        	FinaReceipt receipt = receipts.get(0);
	        	BigDecimal noneInvoicePrice = receipt.getNoneInvoicePrice()==null?BigDecimal.ZERO:receipt.getNoneInvoicePrice();
	        	receipt.setNoneInvoicePrice(noneInvoicePrice.add(s));
	        	receipt.setHxType("0");
            	finaReceiptService.updateById(receipt);
	        }
		}
		return true;
	}


	@Override
	@Transactional
	public boolean updateInvoiceOrPayment(FinaNvoice finaNvoice) {
		// TODO Auto-generated method stub
		if(oConvertUtils.isEmpty(finaNvoice.getId())) {
			throw new RuntimeException("修改失败，未找到该数据");
		}
		FinaNvoice nvoice = baseMapper.selectById(finaNvoice.getId());
		this.updateById(finaNvoice);
        LambdaQueryWrapper<FinaPayment> wrapper=new LambdaQueryWrapper<FinaPayment> ();
        wrapper.eq(FinaPayment::getSupplierId, finaNvoice.getSupplierId());
        wrapper.eq(FinaPayment::getBillType,3);
        wrapper.gt(FinaPayment::getNoneInvoicePrice, 0);
        wrapper.orderByAsc(FinaPayment::getCreateTime);
        List<FinaPayment> payments= paymentService.list(wrapper);
        BigDecimal s = finaNvoice.getInvoicePrice()==null?BigDecimal.ZERO:finaNvoice.getInvoicePrice();
        BigDecimal n = nvoice.getInvoicePrice()==null?BigDecimal.ZERO:nvoice.getInvoicePrice();
		if(s.compareTo(n) > 0 ) {
			s = s.subtract(n);
	        if(payments!=null && payments.size()>0){
	            for (FinaPayment payment : payments) {
	            	BigDecimal noneInvoicePrice = payment.getNoneInvoicePrice()==null?BigDecimal.ZERO:payment.getNoneInvoicePrice();
	                s = s.subtract(noneInvoicePrice);
	                if (s.compareTo(BigDecimal.ZERO) < 0) {
	                    //如果已收减去应收小于零。则将已收减去。
	                	payment.setNoneInvoicePrice(s.setScale(2, BigDecimal.ROUND_DOWN).abs());
	                	payment.setHxType("1");
	                	paymentService.updateById(payment);
	                    break;
	                } else if (s.compareTo(BigDecimal.ZERO) > 0) {
	                    //如果已收减去应收大于0，则将应收改为平账并且继续对其他应收进行平账
	                	payment.setNoneInvoicePrice(BigDecimal.ZERO);
	                	payment.setHxType("0");
	                	paymentService.updateById(payment);
	                }else {
	                	payment.setNoneInvoicePrice(BigDecimal.ZERO);
	                	payment.setHxType("0");
	                	paymentService.updateById(payment);
	                	break;
	                }
	            }
	        }
		}
		if(s.compareTo(n) < 0 ) {
			this.updateById(finaNvoice);
			s = nvoice.getInvoicePrice().subtract(s);
	        if(payments!=null && payments.size()>0){
	        	FinaPayment payment = payments.get(0);
	        	BigDecimal noneInvoicePrice = payment.getNoneInvoicePrice()==null?BigDecimal.ZERO:payment.getNoneInvoicePrice();
	        	payment.setNoneInvoicePrice(noneInvoicePrice.add(s));
	        	payment.setHxType("0");
	        	paymentService.updateById(payment);
	        }
		}
		return true;
	}


	@Override
	@Transactional
	public boolean deleteBatchSK(String ids) {
		// TODO Auto-generated method stub
		//根据id查询要删除的开票数据
		List<FinaNvoice> nvoiceList = baseMapper.selectBatchIds(Arrays.asList(ids.split(",")));
		//存放要修改的收款单数据
		List<FinaReceipt> receiptList = Lists.newArrayList();
		if(nvoiceList!=null && nvoiceList.size()>0) {
			for(FinaNvoice finaNvoice:nvoiceList) {
				//查询未开票金额大于0的收款数据
				LambdaQueryWrapper<FinaReceipt> wrapper=new LambdaQueryWrapper<FinaReceipt> ();
		        wrapper.eq(FinaReceipt::getCustomerId, finaNvoice.getCustomerId());
		        wrapper.eq(FinaReceipt::getBillType,1);
		        wrapper.gt(FinaReceipt::getNoneInvoicePrice, 0);
		        wrapper.orderByAsc(FinaReceipt::getCreateTime);
		        List<FinaReceipt> receipts= finaReceiptService.list(wrapper);
		        BigDecimal s = finaNvoice.getInvoicePrice()==null?BigDecimal.ZERO:finaNvoice.getInvoicePrice();
		        if(receipts!=null && receipts.size()>0){
		        	FinaReceipt receipt = receipts.get(0);
		        	BigDecimal noneInvoicePrice = receipt.getNoneInvoicePrice()==null?BigDecimal.ZERO:receipt.getNoneInvoicePrice();
		        	receipt.setNoneInvoicePrice(noneInvoicePrice.add(s));
		        	receipt.setHxType("0");
		        	receiptList.add(receipt);
		        }
			}
			finaReceiptService.updateBatchById(receiptList);
		}
        this.removeByIds(Arrays.asList(ids.split(",")));
        return true;
	}


	@Override
	public boolean deleteBatchFK(String ids) {
		// TODO Auto-generated method stub
		//根据id查询要删除的开票数据
		List<FinaNvoice> nvoiceList = baseMapper.selectBatchIds(Arrays.asList(ids.split(",")));
		//存放要修改的付款单数据
		List<FinaPayment> paymentList = Lists.newArrayList();
		if(nvoiceList!=null && nvoiceList.size()>0) {
			for(FinaNvoice finaNvoice:nvoiceList) {
				//查询未开票金额大于0的付款数据
				LambdaQueryWrapper<FinaPayment> wrapper=new LambdaQueryWrapper<FinaPayment> ();
		        wrapper.eq(FinaPayment::getSupplierId, finaNvoice.getSupplierId());
		        wrapper.eq(FinaPayment::getBillType,1);
		        wrapper.gt(FinaPayment::getNoneInvoicePrice, 0);
		        wrapper.orderByAsc(FinaPayment::getCreateTime);
		        List<FinaPayment> payments= paymentService.list(wrapper);
		        BigDecimal s = finaNvoice.getInvoicePrice()==null?BigDecimal.ZERO:finaNvoice.getInvoicePrice();
		        if(payments!=null && payments.size()>0){
		        	FinaPayment payment = payments.get(0);
		        	BigDecimal noneInvoicePrice = payment.getNoneInvoicePrice()==null?BigDecimal.ZERO:payment.getNoneInvoicePrice();
		        	payment.setNoneInvoicePrice(noneInvoicePrice.add(s));
		        	payment.setHxType("0");
		        	paymentList.add(payment);
		        }
			}
			paymentService.updateBatchById(paymentList);
		}
        this.removeByIds(Arrays.asList(ids.split(",")));
		return true;
	}



}
